package com.wenjh.jdmzt.android.synctask;

import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.net.ssl.SSLEngineResult.HandshakeStatus;

import android.graphics.Bitmap;
import android.widget.ImageView;

import com.wenjh.jdmzt.android.view.HandyListView;
import com.wenjh.jdmzt.service.model.Image;
import com.wenjh.jdmzt.util.ImageUtil;
import com.wenjh.jdmzt.R;

public class LoadImageUtil {
	private static final Map<String, SoftReference<Bitmap>> imagePool = new HashMap<String, SoftReference<Bitmap>>();
	
	public static void loadImage(Image image, ImageView imageView, HandyListView listView, boolean setdefalut, boolean zoomWidth) {
		String imageIndex = getImageIndex(image.getImageId(), zoomWidth);
		Bitmap bitmap = getImage(imageIndex);
		imageView.setTag(R.id.tag_item_imageid, image.getImageId());
		if(bitmap == null) {
			if(setdefalut) {
				imageView.setImageResource(R.drawable.bg_transparent);
			} else {
				imageView.setImageBitmap(null);
			}

			ImageCallback callback = null;
			ImageTag imageTag = (ImageTag) imageView.getTag();
			if(imageTag == null) {
				imageTag = new ImageTag(imageView);
				imageView.setTag(imageTag);
			}
			imageTag.zoomWidth = zoomWidth;
			imageTag.imageid = image.getImageId();
			
			// 下载于之前就开始，只更换callback的imageview
			if(image.isImageLoading() && (callback = image.getImageCallback()) != null) {
				callback.addImageTag(imageTag);
			} else {
				LoadImageTask imageTask = new LoadImageTask(image);
				// list滚动过程中，只加载已缓存的图片
				boolean doload = false;
				if(listView != null) {
					if(listView.getLoadPolicy() == HandyListView.DataLoadPolicy.Anytime) {
						doload = true;
					} else if(listView.getLoadPolicy() == HandyListView.DataLoadPolicy.Easy) {
						// 滑动过程中只加载本地已有的图片,这是easy策略
						if(listView.isScrolling()) {
							doload = imageTask.isLocalExists();
						} else {
							doload = true;
						}
					} else if(listView.getLoadPolicy() == HandyListView.DataLoadPolicy.Idle) {
						// 没有在滚动的时候加载
						doload = !listView.isScrolling();
					}
				}
				
				if(doload) {
					image.setImageLoading(true);
					image.setImageCallback(new ImageCallback(imageTag, image));
					imageTask.addCallback(image.getImageCallback());
					imageTask.execute();
				}
			}
		} else {
			imageView.setImageBitmap(bitmap);
		}
	}
	
	/**
	 * 这个实际是一个封装了的imageview，为了将一些图片处理的熟悉集中起来，所以封装了这样一个对象。
	 * <p>图片是要小的，还是要按屏幕宽度处理的，还是要...imageview自己知道</p>
	 * @author wjh
	 *
	 */
	private static class ImageTag {
		WeakReference<ImageView> imageViewRef = null;
		String imageid;
		boolean zoomWidth;
		
		public ImageTag(ImageView imageView) {
			this.imageViewRef = new WeakReference<ImageView>(imageView);
		}

		public ImageView getImageView() {
			return imageViewRef.get();
		}
		
		public void setImageBitmap(Bitmap b, final String imageid) {
			ImageView iv = getImageView();
			
			if(iv != null && this.imageid.equals(iv.getTag(R.id.tag_item_imageid))) {
				final Bitmap bitmap;
				
				Bitmap cacheBitmap = getImage(getImageIndex(imageid, zoomWidth));
				if(cacheBitmap != null) {
					bitmap = cacheBitmap;
				} else if(b != null) {
					if(zoomWidth) {
						int width = iv.getMeasuredWidth()-iv.getPaddingLeft()-iv.getPaddingRight();
						int height = Math.round(((float)width/b.getWidth())*b.getHeight());
						Bitmap zoomBitmap = ImageUtil.zoomBitmap(b, width, height);
						putImage(getImageIndex(imageid, zoomWidth), zoomBitmap);
						putImage(getImageIndex(imageid, false), b);
						bitmap = zoomBitmap;
					} else {
						putImage(getImageIndex(imageid, false), b);
						bitmap = b;
					}
				} else {
					return;
				}
				
				iv.post(new Runnable() {
					@Override
					public void run() {
						ImageView iv = getImageView();
						if(iv != null && imageid.equals(iv.getTag(R.id.tag_item_imageid))) {
							iv.setImageBitmap(bitmap);
						}
					}
				});
				
			}
			
		}
	}
	
	public static String getImageIndex(String imgId, boolean zoomWidth) {
		if(zoomWidth) {
			return imgId+"_z";
		} else {
			return imgId+"_l";
		}
	}
	
	public static class ImageCallback implements Callback<Bitmap> {
		List<WeakReference<ImageTag>> imageTags = null;
		Image image = null;
		
		public ImageCallback(ImageTag imageTag, Image image) {
			this.imageTags = new ArrayList<WeakReference<ImageTag>>();
			this.imageTags.add(new WeakReference<ImageTag>(imageTag));
			this.image = image;
		}
		
		public void addImageTag(ImageTag imageTag) {
			this.imageTags.add(new WeakReference<ImageTag>(imageTag));
		}
		
		@Override
		public void afterRun(Bitmap t) {
			image.setImageLoading(false);
			image.setImageCallback(null);
			
			if(t != null) {
				// 将图片交给imagtag处理，可能涉及到重复调用，因此用一个set去重
				Set<ImageTag> callsSet = new HashSet<LoadImageUtil.ImageTag>();
				for (int i = 0; i < imageTags.size(); i++) {
					ImageTag imageTag = imageTags.get(i).get();
					if(imageTag != null) {
						if(!callsSet.contains(callsSet)) {
							imageTag.setImageBitmap(t, this.image.getImageId());
						}
					}
				}
			}
		}
		
	}
	
	public static Bitmap getImage(String imageid) {
		Bitmap bitmap = imagePool.get(imageid) == null ? null : imagePool.get(imageid).get();
		
		if(bitmap != null && bitmap.isRecycled()) {
			bitmap = null;
			imagePool.remove(imageid);
		}
		
		return bitmap;
	}

	public static void releaseAll() {
		Map<String, SoftReference<Bitmap>> map = new HashMap<String, SoftReference<Bitmap>>();
		map.putAll(imagePool);
		imagePool.clear();

		for (Entry<String, SoftReference<Bitmap>> entry : map.entrySet()) {
			Bitmap b = entry.getValue().get();
			if(b != null) {
				b.recycle();
			}
		}
	}

	public static void putImage(String imageid, Bitmap bitmap) {
		if(bitmap == null) {
			return;
		}
		
		imagePool.put(imageid, new SoftReference<Bitmap>(bitmap));
	}
}
